home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / ada / adaed-1.11 / adaed-1 / Adaed-1.11.0a / adamrg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-07  |  15.7 KB  |  714 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. /* adamrg - merge error and ada source files to make listing */
  11.  
  12. #include "config.h"
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <ctype.h>
  16. #include <malloc.h>
  17. #include <string.h>
  18. #ifdef IBM_PC
  19. #include "stdlib.h"
  20. #else
  21. #endif
  22. #include "miscprots.h"
  23. #include "adamrgprots.h"
  24.  
  25.  
  26. #ifdef vms
  27. /* Temporary fix to avoid missing adacomp.h
  28. #define fork vfork
  29. #define unlink delete
  30. #include "adacomp.h"
  31. #include descrip
  32. #include <file.h>
  33. #include <types.h>
  34. #include <stat.h>
  35. */
  36. #else
  37. #ifndef IBM_PC
  38. #include <sys/types.h>
  39. #include <sys/file.h>
  40. #endif
  41. #endif
  42.  
  43. #ifdef SYSTEM_V
  44. #include <fcntl.h>
  45. #endif
  46. #ifndef IBM_PC
  47. #include <signal.h>
  48. #endif
  49.  
  50. #ifdef BSD
  51. #include "time.h"
  52. #include <sys/resource.h>
  53. #endif
  54.  
  55.  
  56. #ifdef IBM_PC
  57. #include "time.h"
  58. #else
  59. typedef long Time_type;
  60. #endif
  61.  
  62. /*
  63.  * Author: Alex Dreyzen Jan,1984
  64.  * Revised: Brian Siritzky, June 1984
  65.  * Revised: J. Chiabaut, November 1984
  66.  * Revised: D. Shields, May 1985
  67.  * Revised: D. Shields, July 1985
  68.  * Revised: G. Schenker, April 1986
  69.  * Revised: J. Chiabaut, May 1986
  70.  * Revised: D. Shields, July 1986
  71.  *    make into separate procedure, use single structure for all
  72.  *    messages, simplify logic
  73.  *           
  74.  */
  75.  
  76. /*
  77.  * This program takes two arguments giving the name of an adafile and 
  78.  * the msgfile/listfile  and then merges the messages in the file with 
  79.  * suffix '.msg' and source in file with suffix '.ada' to produce 
  80.  * listing file with suffix '.lis'.
  81.  *
  82.  * Function  main(argc,argv)  activates     functions   init_msg_map(),
  83.  * merge_ada_msg().
  84.  * Function init_msg_map()  counts  lines in the filename.msg,
  85.  * allocates space to store the keys and offsets of each  message,
  86.  * and sorts offsets in ascending order of the keys. Function
  87.  * printmsg() reads messages 
  88.  *
  89.  *
  90.  * Message format is:
  91.  *
  92.  * type_of_msg line_left col_left line_right col_right    <TAB>    message
  93.  *
  94.  * Where type_of_msg is one of :
  95.  *
  96.  *   PRAGMA_LIST_ON 1
  97.  *   PRAGMA_LIST_OFF 2
  98.  *   PRAGMA_LIST_ERR 3
  99.  *   PRAGMA_PAGE 4
  100.  *   ERR_LEXICAL 10
  101.  *   ERR_SYNTAX 11
  102.  *   ERR_SEMANTIC 12
  103.  *   ERR_WARNING 13
  104.  *   INFORMATION 14
  105.  *   ERR_BIND 15
  106.  *   ERR_COMPILER 16
  107.  *
  108.  *  Note that these are defined in config.h
  109.  */
  110.  
  111. #define MAXLINE 512
  112.  
  113. #define PAGESIZE 55
  114.  
  115. #define VERSION_NO "1.7.3"
  116.  
  117. extern int  n_lex_err, n_syntax_err, n_semantic_err, n_binding_err, 
  118.             n_warning_err, n_generator_err, n_information;
  119. char    header[80];        /* header for output */
  120. int    pageno = 0;        /* output page number */
  121. int    realline = 0;        /* actual number of lines output */
  122. int    n_error = 0;        /* Number of errors */
  123. int    n_lex_err = 0;        /* Counts of the various kinds of messages */
  124. int    n_syntax_err = 0;
  125. int    n_semantic_err = 0;
  126. int    n_generator_err = 0;
  127. int    n_binding_err = 0;
  128. int    n_warning_err = 0;
  129. int     n_information = 0;
  130. /* Pointers to message, ada, and list files */
  131. FILE *msgfile, *adafile, *listfile;
  132. char   *pmsg,
  133.        *pada;
  134. int     line1,
  135.         line2,
  136.         col1,
  137.         col2,
  138.         error_type;
  139.  
  140. int    msgs_total,
  141.     m_type,
  142.     line_msg,
  143.     line_ada = 0,
  144.     list_on = 1,
  145.     msgs_read = 0;
  146. typedef struct Msg_ent {
  147.     short    msg_type;        /* message type */
  148.     short    msg_line1;        /* starting line */
  149.     short    msg_col1;        /* starting column */
  150.     short    msg_line2;        /* ending line */
  151.     short    msg_col2;        /* ending column */
  152.     short    msg_num;        /* message number (for stable sort) */
  153.     char        *msg_text;        /* message text */
  154.     struct    Msg_ent *msg_prev;    /* link to previous message */
  155. } Msg_ent;
  156. typedef struct Msg_ent *Msg;
  157. Msg *msg_array;
  158. char   *data, *line;
  159. int    adaeof = 0;
  160. char blankl[132] ;    /* blank line for underscore */
  161. char blanks[132];
  162. char dashl[132] ;    /* dash line for underscore */
  163. char dashes[132];
  164.  
  165. static void getada();
  166. static void getmsg();
  167. static void merge_ada_msg();
  168. static void pblank(int);
  169. static void underscore(int, int);
  170. static void printada();
  171. static void printmsg();
  172. static void newpage();
  173. static void newlin();
  174. static int init_msg_map(char *);
  175. static int compar(Msg *, Msg *);
  176. static char *sindex(char *, char);
  177. static int getlin();
  178. static char *msgtype(int);
  179.  
  180. int mrg(char *adafilename, char *msgfilename, char *listfilename,
  181.   char *list_arg)                                                    /*;mrg*/
  182. {
  183.     char   *s;
  184. #ifndef IBM_PC
  185.     Time_type bintim;
  186. #else
  187.     time_t bintim;
  188. #endif
  189.     char   *day, *month, *date, *clock, *year;
  190.     int list_opt;
  191. #ifdef vms
  192.     struct      dsc$descriptor_s string_desc;
  193. #endif
  194.  
  195.     int    i,istatus;
  196.  
  197.  
  198.     list_opt = strcmp(list_arg,"1") == 0;
  199.  
  200.     for (i=0;i<131;i++) blanks[i] = ' ';
  201.     for (i=0;i<131;i++) dashes[i] = '-';
  202.     blanks[131] = '\0';
  203.     dashes[131] = '\0';
  204.     data = malloc(MAXLINE);
  205.     line = data;
  206.  
  207.  
  208. /*
  209.  * if no adafile is given or not open, print only messages
  210.  */
  211.    adafile = efopen(adafilename, "r", "t");
  212. /*
  213.  * returns if the message file is empty and a listing is not required
  214.  */
  215.    istatus = init_msg_map(msgfilename);
  216. #ifdef DEBUG_MRG
  217.    printf("init_msg status %d\n",istatus);
  218. #endif
  219.    if (istatus==-1) return RC_INTERNAL_ERROR;
  220.    if(!istatus && !list_opt) return 0;
  221. #ifdef DEBUG_MRG
  222. printf("opening listfile %s\n",listfilename);
  223. #endif
  224.    listfile = efopen(listfilename, "w", "t");
  225.    if (listfile==(FILE *)0) {
  226. #ifdef vms
  227.         LIB$SIGNAL(MSG_NOLIST);
  228. #else
  229.         fprintf(stderr, "Cannot open file %s.\n", listfilename);
  230. #endif
  231.         listfile = stderr;
  232.    }
  233.  
  234. /* get the date and split it */
  235. #ifdef DEBUG_MRG
  236.     printf("get time\n");
  237. #endif
  238. /*  s = "Sun Apr 21 08:00:00 1985\n"; */
  239. #ifndef IBM_PC
  240.     bintim = time((long *) 0);
  241.     s = (char *) ctime(&bintim);
  242. #else
  243.     time(&bintim);
  244.     s = ctime(&bintim);
  245. #endif
  246.     day = s;
  247.     s += 3;
  248.     *s++ = '\0';
  249.     month = s;
  250.     s += 3;
  251.     *s++ = '\0';
  252.     date = s;
  253.     s += 2;
  254.     *s++ = '\0';
  255.     clock = s;
  256.     s += 8;
  257.     *s++ = '\0';
  258.     year = s;
  259.     s += 4;
  260.     *s = '\0';
  261.  
  262.     sprintf(header,
  263.         "NYU Ada/ED-C %s  %-15s  %s  %s %s %s  %s  PAGE   ",
  264.         VERSION_NO, OP_SYS, day, date, month, year, clock);
  265.     newpage();
  266. #ifdef DEBUG_MRG
  267. printf("post header\n");
  268. #endif
  269.     if (adafile!=(FILE *)0) {
  270.         getada();
  271.         realline++;
  272.     }
  273.     else {
  274.         line_ada = -1;
  275.         adaeof = EOF;
  276.         pada = (char *) 0;
  277.     }
  278.     getmsg();
  279.     if (pmsg == (char *) 0)
  280.         line_msg = 9999;
  281.     merge_ada_msg();
  282.     n_error = n_lex_err + n_syntax_err + n_semantic_err + n_binding_err
  283.       + n_generator_err;
  284.     if (n_error) {
  285.         fprintf(listfile, "\n     %d error%s detected\n", n_error,
  286.           ((n_error == 1) ? "" : "s"));
  287. #ifndef vms
  288.     /* print again to the terminal if it is not stderr */
  289.     if (listfile != stderr) {
  290.         fprintf(stderr,"%d error%s detected\n", n_error,
  291.           ((n_error == 1) ? "" : "s"));
  292.     }
  293. #endif
  294.     }
  295.     else {
  296.       fprintf(listfile, "\n    No errors detected\n");
  297.     }
  298. #ifdef vms
  299.     if(n_error+n_warning_err+n_information) {
  300.         sprintf(header,
  301.        "%s completed with\r\n\t\t%d error(s), %d warning(s), and %d\0",
  302.         adafilename,      n_error,     n_warning_err,     n_information);
  303.         string_desc.dsc$w_length = strlen(header);
  304.         string_desc.dsc$b_dtype = DSC$K_DTYPE_T;
  305.         string_desc.dsc$b_class = DSC$K_CLASS_S;
  306.         string_desc.dsc$a_pointer = header;
  307.         LIB$SIGNAL(MSG_SUMMARY,1,&string_desc);
  308.     }
  309. #endif
  310.     return 1;
  311. }
  312.  
  313. static void getada()                                    /*;getada */
  314. {
  315.     line_ada++;
  316.     adaeof = getlin();
  317.     if (adaeof != EOF)
  318.     pada = data;
  319.     else
  320.     pada = (char *) 0;
  321. }
  322.  
  323. static void getmsg()                                    /*;getmsg */
  324. {
  325.     Msg msgp;
  326.     if (msgs_read < msgs_total) {
  327.         msgp = msg_array[msgs_read];
  328. #ifdef DEBUG_MRG
  329.         printf("getmsg msgs_read %d msgp %p\n",msgs_read, msgp);
  330. #endif
  331.         pmsg = msgp -> msg_text;
  332.         line1 = msgp ->msg_line1;
  333.         line2 = msgp ->msg_line2;
  334.         line_msg = line2;
  335.         col1 = msgp -> msg_col1;
  336.         col2 = msgp -> msg_col2;
  337.         error_type = msgp -> msg_type ;
  338.         msgs_read++;
  339.         return;
  340.     }
  341.     else {
  342.         line_msg = 9999;
  343.         pmsg = (char *) 0;
  344.         return;
  345.     }
  346.  
  347. }
  348.  
  349. static void merge_ada_msg()                            /*;merge_ada_msg */
  350. {
  351.     int        dummsg;
  352.  
  353.     while((pmsg != (char *) 0) ||(pada != (char *) 0)) {
  354.         dummsg = 0;
  355.         if (line_msg < line_ada) {/* only if adafile is present */
  356.             while((line_msg < line_ada) && pmsg != (char *) 0) {
  357.                 printmsg();
  358.                 getmsg();
  359.             }
  360.         }
  361.  
  362.     if (line_msg == line_ada) {/* only if adafile is present */
  363.         switch(m_type) {
  364.         case PRAGMA_PAGE:
  365.             dummsg = 1;
  366.             if ((pada != (char *) 0)) {
  367.             if (list_on) {
  368.                 printada();
  369.             }
  370.             getada();
  371.             }
  372.             if (list_on)
  373.             newpage();
  374.             break;
  375.         case PRAGMA_LIST_OFF:
  376.             dummsg = 1;
  377.             if (adaeof != EOF) {
  378.             if (list_on)
  379.                 printada();
  380.             getada();
  381.             }
  382.             list_on = 0;
  383.             break;
  384.         case PRAGMA_LIST_ON:
  385.             dummsg = 1;
  386.             if (adaeof != EOF) {
  387.             printada();
  388.             getada();
  389.             }
  390.             list_on = 1;
  391.             break;
  392.         default:
  393.             dummsg = 0;
  394.             if (adaeof != EOF) {
  395.             printada();
  396.             getada();
  397.             }
  398.             printmsg();
  399.         }
  400.         getmsg();
  401.     }
  402.  
  403.     if (line_msg >= line_ada) {/* if only one message on line */
  404.         if (list_on) {
  405.             if (!dummsg)
  406.                 newlin();
  407.             while((line_msg > line_ada) && adaeof != EOF) {
  408.                    printada();
  409.                    getada();
  410.             }
  411.         }
  412.         else        /* read in lines, until the next message or EOF */
  413.             while((line_msg > line_ada) && adaeof != EOF)
  414.                 getada();
  415.  
  416.         if (adaeof == EOF) {/* adafile is not present or EOF reached */
  417.             while((pmsg != (char *) 0) &&(line_msg < 9999)) {
  418.                 printmsg();
  419.                 getmsg();
  420.             }
  421.             newlin();
  422.             while(pmsg != (char *) 0) {
  423.                 printmsg();
  424.                 getmsg();
  425.             }
  426.         }
  427.     }
  428.     }
  429. }
  430.  
  431. #define printhat(col)pblank(col-1);fprintf(listfile,"^");fprintf(listfile,"\n")
  432.  
  433. static void pblank(int col)                                        /*;pblank */
  434. {
  435.     strcpy(blankl,blanks);
  436.     realline++;
  437.     if (col > 0) {
  438.         blankl[col] = '\0';
  439.         fprintf(listfile, "%s", blankl);
  440.         blankl[col] = ' ';
  441.     }
  442. }
  443.  
  444. static void underscore(int col1, int col2)                    /*;underscore */
  445. {
  446.     strcpy(dashl,dashes);
  447.     pblank(col1 - 1);
  448.     fprintf(listfile, "<");
  449.     if (col2 - col1 > 1) {
  450.         dashl[col2 - col1 - 1] = '\0';
  451.         fprintf(listfile, "%s", dashl);
  452.         dashl[col2 - col1 - 1] = '-';
  453.     }
  454.     fprintf(listfile, ">");
  455.     fprintf(listfile, "\n");
  456. }
  457.  
  458. static void printada()                                        /*;printada */
  459. {
  460.     if (++realline >= PAGESIZE)
  461.         newpage();
  462.     fprintf(listfile, "%4d:   %s", line_ada, pada);
  463. }
  464.  
  465. /*    This function prints error message, underscoring
  466.     the corresponding place in the source line        */
  467.  
  468. static void printmsg()                                        /*;printmsg */
  469. {
  470.     if (error_type >= ERR_LEXICAL) {
  471.         if (error_type < INFORMATION) {
  472.             if (adafile!=(FILE *)0)
  473.                 if (line1 == line2)
  474.                     if (col2 - col1 < 1) {
  475.                         printhat(col1 + 8);
  476.                     }
  477.                     else {
  478.                         underscore(col1 + 8, col2 + 8);
  479.                     }
  480.             else {
  481.                 fprintf(listfile,
  482.                   "\n       Between line %d column %d and line %d column %d\n",
  483.                   line1, col1, line2, col2);
  484.                 realline += 2;
  485.             }
  486.             else {
  487.                 realline += 2;
  488.                 if (line1 == line2)
  489.                     fprintf(listfile,
  490.                       "\n       Line %d between column %d and column %d\n",
  491.                       line1, col1, col2);
  492.                 else
  493.                     fprintf(listfile,
  494.                     "\n       Between line %d column %d and line %d column %d\n",
  495.                       line1, col1, line2, col2);
  496.             }
  497.         }
  498.     fprintf(listfile, "%s %s\n", msgtype(error_type), sindex(pmsg, '\t'));
  499.     if (realline++ >= PAGESIZE)
  500.         newpage();
  501.     }
  502. }
  503.  
  504. static void newpage()                                    /*;newpage */
  505. {
  506.     /*
  507.      * this procedure outputs a form feed, resets the line counter
  508.      * and prints the standard header at the top of the page
  509.      */
  510.     pageno++;
  511.     realline = 1;
  512.     fprintf(listfile, "\f");
  513.     /* Add the page number to the end of the string */
  514.     fprintf(listfile, "%s %d\n\n", header, pageno);
  515. }
  516.  
  517. static void newlin()                                            /*;newlin */
  518. {
  519.     if ((++realline >= PAGESIZE))
  520.     newpage();
  521.     else
  522.     fprintf(listfile, "\n");
  523. }
  524.  
  525. static int init_msg_map(char *msgfilename)                /*;init_msg_map */
  526. {
  527.     int    i, line1,line2,col1,col2,type;
  528.     int    nitems;
  529.     int    tab_found;
  530.     Msg    m_prev;
  531.     char *dp;
  532.     Msg        msg;
  533.  
  534.  
  535.     msgfile = efopen(msgfilename, "r","t");
  536.     if (msgfile==(FILE *)0) /* cannot open file */
  537.     return(FALSE);
  538.     m_prev = (Msg)0;
  539. #ifdef DEBUG_MRG
  540.     printf("start reading messages\n");
  541. #endif
  542.     while (fgets(data, MAXLINE, msgfile) != (char *)0) {
  543.         /* delete trailing newline */
  544.         data[strlen(data)-1] = '\0';
  545.         msg = (Msg) malloc(sizeof(Msg_ent));
  546.         if (msg==(Msg)0) {
  547. #ifdef vms
  548.             LIB$SIGNAL(MSG_NOMEM);
  549. #else
  550.             fprintf(stderr,"Cannot read error messages\n");
  551.             return -1;
  552. #endif
  553.         }
  554.         nitems = sscanf(data,"%d %d %d %d %d",
  555.           &type, &line1, &col1, &line2, &col2);
  556.         if (nitems!=5) {
  557.             printf("scanned %d\n",nitems);
  558.             printf(data,"%s\n");
  559.             chaos("bad message line");
  560.         }
  561.         msgs_total++;
  562.         msg->msg_num = msgs_total;
  563.         msg->msg_type = type;
  564.         msg->msg_line1 = line1;
  565.         msg->msg_col1 = col1;
  566.         msg->msg_line2 = line2;
  567.         msg->msg_col2 = col2;
  568.         msg->msg_prev = m_prev;
  569. #ifdef DEBUG_MRG
  570.         printf("new msg %p previous %p\n", msg, m_prev);
  571. #endif
  572.         m_prev = msg;
  573.         /* now find message text */
  574.         dp = data;
  575.         tab_found = 0;
  576.         while (*dp != '\0') {    /* skip to first tab */
  577.             if (*dp=='\t') {
  578.                 tab_found = 1;
  579.                 break;
  580.             }
  581.             dp++;
  582.         }
  583.         if (!tab_found) dp = data;
  584.         msg->msg_text = strjoin(dp,""); /* copy message text */
  585. #ifdef DEBUG_MRG
  586.         printf("mrg message %d type %d line1 %d col1 %d line2 %d col2 %d\n%s\n",
  587.          msg->msg_num, msg->msg_type, msg->msg_line1, msg->msg_col1,
  588.          msg->msg_line2, msg->msg_col2, msg->msg_text);
  589. #endif
  590.     }
  591.     /* now form msg_array, array of pointers to messages */
  592.     if (msgs_total) {
  593.         msg_array = (Msg *) calloc(msgs_total, sizeof(Msg));
  594.         if (msg_array == (Msg *)0) {
  595. #ifdef vms
  596.         LIB$SIGNAL(MSG_NOMEM);
  597. #else
  598.         fprintf(stderr,"Cannot read error messages\n");
  599.         return -1;
  600. #endif
  601.         }
  602.         for (i=msgs_total-1;i>=0;i--) {
  603.             msg_array[i] = m_prev;
  604. #ifdef DEBUG_MRG
  605.         printf("init msg_array i %d ptr %p m_prev %p\n",i,msg_array+i,m_prev);
  606. #endif
  607.         m_prev = m_prev->msg_prev;
  608. #ifdef DEBUG_MRG
  609.         printf("m_prev set to %p\n",m_prev);
  610. #endif
  611.         }
  612.     }
  613.     else {
  614.         msg_array = (Msg *) 0;
  615.     }
  616.  
  617.     if (msgs_total) {
  618.         qsort(msg_array, msgs_total, sizeof(Msg),
  619.           ( int (*)(const void *, const void *)) compar);
  620.     }
  621.     return msgs_total;
  622. }
  623.  
  624. static int  compar(Msg *a, Msg *b)                                /*;compar */
  625. {
  626.     Msg c,d;
  627.  
  628.     c = *a; d = *b;
  629.     /* compare by lines, then by columns */ 
  630.     if (c->msg_line2 >d->msg_line2) return 1;
  631.     else if (c->msg_line2 < d->msg_line2) return -1;
  632.     /* if same line, use message number */
  633.     else if (c->msg_num >d->msg_num) return 1;
  634.     else if (c->msg_num <d->msg_num) return -1;
  635.     return 0; /* if same */
  636. }
  637.  
  638. /* This is probably meant to be 4.2 index(), but give it separate name for now*/
  639. static char *sindex(char *s, char c)                        /*;sindex */
  640. {
  641.     while(*s != c) {
  642.         if ((*s == '\0') ||(*s == '\n'))
  643.             return s;
  644.         s++;
  645.     }
  646.     return++ s;
  647. }
  648.  
  649.  
  650. static int getlin()                                            /*;getlin */
  651. {
  652.     /* this is a stripped down version of getlin in adalex.c */
  653.     int        ch, ind = 0;
  654.  
  655.     if (feof(adafile))
  656.         return EOF;
  657.     for (;;) {
  658.         ch = getc(adafile);
  659.         if (ch == EOF)
  660.             break;
  661.         if (ch <= 13 && ch >= 10)
  662.             break;
  663.            if (ind == MAXLINE) {
  664.                while((ch = getc(adafile)) != EOF && !(10 <= ch && ch <= 13));
  665.                break;
  666.            }
  667.            else
  668.                data[ind++] = ch;
  669.     }
  670.  
  671.     data[ind++] = '\n';
  672.     data[ind] = '\0';
  673.     if (ch == EOF && !ind)
  674.         return EOF;
  675.     return (0);
  676. }
  677.  
  678. char *msgtype(int n)        /*;msgtype */
  679. {
  680.     char   *s;
  681.  
  682.     switch(n) {
  683.     case ERR_LEXICAL:
  684.         s = "*** ERROR:";
  685.         n_lex_err++;
  686.         break;
  687.     case ERR_SYNTAX:
  688.         s = "*** ERROR:";
  689.         n_syntax_err++;
  690.         break;
  691.     case ERR_SEMANTIC:
  692.         s = "*** ERROR:";
  693.         n_semantic_err++;
  694.         break;
  695.     case ERR_COMPILER:
  696.         s = "*** ERROR:";
  697.         n_generator_err++;
  698.         break;
  699.     case ERR_WARNING:
  700.         s = "* WARNING:";
  701.         n_warning_err++;
  702.         break;
  703.     case INFORMATION:
  704.         s = "    ";
  705.             n_information++;
  706.         break;
  707.     case ERR_BIND:
  708.         s = "*** ERROR:";
  709.         n_binding_err++;
  710.         break;
  711.     }
  712.     return (s);
  713. }
  714.